#include <iostream>
#include <ctime>
#include <windows.h>
#include <stdlib.h>
#include <math.h>
using namespace std;

void display();                                 // 程序主界面
void FunChoice();                               // 功能跳转
void GetCurTime();                              // 获取当前时间

void GetLunar();                         // 1.农历
void GetGre();                           // 2.公历
void PrintMonth(int year, int month);    // 3.月历
void GetDays();                          // 4.某天距离今天的天数
void GetDates();                         // 5.距离今天相应天数的日期
void DiffInDays();                       // 6.任意日期天数差
void PrintSolarTerms();                  // 7.节气
void GetFestival();                      // 8.节日

tm* NT;
int NowDate[4];
time_t nowtime; // time_t是一种数据类型，表示从纪元日（1970年1月1日）到今的时间秒数

const char* weekdays[] = {"日", "一", "二", "三", "四", "五", "六"};

const char* Gan[] = {"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"}; 
const char* Zhi[] = {"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"}; 

const int MonthDays[] = {
	31, 28, 31, 30, 31, 30, 
	31, 31, 30, 31, 30, 31
}; // 每月天数数组(非闰年)

const char* LunarMonths[] = {
	"正", "二", "三", "四", "五", "六", 
	"七", "八", "九", "十", "冬", "腊"
}; // 农历月份名称

const char* LunarDays[] = {
    "初一", "初二", "初三", "初四", "初五", "初六", "初七", "初八", "初九", "初十",
    "十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八", "十九", "二十",
    "廿一", "廿二", "廿三", "廿四", "廿五", "廿六", "廿七", "廿八", "廿九", "三十"
}; // 农历日期名称

const char* ChineseNums[] = {
	"〇", "一", "二", "三", "四", "五", 
	"六", "七", "八", "九", "十"
};// 添加农历数字的中文表示

// 1900-2100年农历数据信息
// 数据格式: 每个数字的二进制表示
// 前4位：0 = 小月(29天), 1 = 大月(30天)
// 中间12位：每一位表示这一年的月份，1 表示该月为30天，0 表示该月为29天
// 最后4位：表示闰月的月份，0 表示没有闰月
static const unsigned int LUNAR_INFO[] = {
    0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2,  // 1900-1909
    0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977,  // 1910-1919
    0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,0x052f2,0x04970,  // 1920-1929
    0x064b0,0x074a3,0x0ea50,0x06b58,0x055c0,0x0ab60,0x096d5,0x092e0,0x0c960,0x0d954,  // 1930-1939
    0x0d4a0,0x0da50,0x07552,0x056a0,0x0abb7,0x025d0,0x092d0,0x0cab5,0x0a950,0x0b4a0,  // 1940-1949
    0x0baa4,0x0ad50,0x055d9,0x04ba0,0x0a5b0,0x15176,0x052b0,0x0a930,0x07954,0x06aa0,  // 1950-1959
    0x0ad50,0x05b52,0x04b60,0x0a6e6,0x0a4e0,0x0d260,0x0ea65,0x0d530,0x05aa0,0x076a3,  // 1960-1969
    0x096d0,0x04afb,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45,0x0b5a0,0x056d0,  // 1970-1979
    0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,0x06d20,0x0ada0,0x14b63,0x09370,  // 1980-1989
    0x049f8,0x04970,0x064b0,0x168a6,0x0ea50,0x06b20,0x1a6c4,0x0aae0,0x0a2e0,0x0d2e3,  // 1990-1999
    0x0c960,0x0d557,0x0d4a0,0x0da50,0x05d55,0x056a0,0x0a6d0,0x055d4,0x052d0,0x0a9b8,  // 2000-2009
    0x0a950,0x0b4a0,0x0b6a6,0x0ad50,0x055a0,0x0aba4,0x0a5b0,0x052b0,0x0b273,0x06930,  // 2010-2019
    0x07337,0x06aa0,0x0ad50,0x14b55,0x04b60,0x0a570,0x054e4,0x0d160,0x0e968,0x0d520,  // 2020-2029
    0x0daa0,0x16aa6,0x056d0,0x04ae0,0x0a9d4,0x0a2d0,0x0d150,0x0f252,0x0d520,0x0d5a0,  // 2030-2039
    0x0dd60,0x15b63,0x06d20,0x0ada0,0x0ab60,0x09370,0x04af0,0x04970,0x064b0,0x074a3,  // 2040-2049
    0x0ea50,0x06b58,0x055c0,0x0ab60,0x096d5,0x092e0,0x0c960,0x0d954,0x0d4a0,0x0da50,  // 2050-2059
    0x07552,0x056a0,0x0abb7,0x025d0,0x092d0,0x0cab5,0x0a950,0x0b4a0,0x0baa4,0x0ad50,  // 2060-2069
    0x055d9,0x04ba0,0x0a5b0,0x15176,0x052b0,0x0a930,0x07954,0x06aa0,0x0ad50,0x05b52,  // 2070-2079
    0x04b60,0x0a6e6,0x0a4e0,0x0d260,0x0ea65,0x0d530,0x05aa0,0x076a3,0x096d0,0x04afb,  // 2080-2089
    0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45,0x0b5a0,0x056d0,0x055b2,0x049b0,  // 2090-2099
    0x0a577                                                                           // 2100
}; 

typedef struct {
    char name[20];
    int month;
    double param;
} SolarTerm;

// 节气计算参数表（基于天文简化公式）
const SolarTerm terms[24] = {
    {"立春", 2, 3.87},   {"雨水", 2, 18.73},  {"惊蛰", 3, 5.63},   {"春分", 3, 20.646},
    {"清明", 4, 5.381},  {"谷雨", 4, 20.22},  {"立夏", 5, 5.47},   {"小满", 5, 21.04},
    {"芒种", 6, 5.86},   {"夏至", 6, 21.37},  {"小暑", 7, 7.58},   {"大暑", 7, 23.08},
    {"立秋", 8, 7.93},   {"处暑", 8, 23.13},  {"白露", 9, 7.87},   {"秋分", 9, 23.04},
    {"寒露", 10, 8.14},  {"霜降", 10, 23.19}, {"立冬", 11, 7.88},  {"小雪", 11, 22.19},
    {"大雪", 12, 7.18},  {"冬至", 12, 21.94}, {"小寒", 1, 5.405},  {"大寒", 1, 20.12}
}; 

// 控制台主界面
void display() {
	system("cls");
	system("color f0");
	
	printf("************************************************\n");
	printf("\t    欢迎使用万年历系统\n"); // 标题试着能不能加粗
	GetCurTime(); // 当前时间进行高亮
	printf("************************************************\n");
	printf("\t    [1] 查询农历\n");
	printf("\t    [2] 查询公历\n");
	printf("\t    [3] 显示月历\n");
	printf("\t    [4] 查询某天距今天的天数\n");
	printf("\t    [5] 查询距今天相应天数的日期\n");
	printf("\t    [6] 查询两日期之间的天数差\n");
	printf("\t    [7] 查询二十四节气\n");
	printf("\t    [8] 查询节日\n");
	printf("************************************************\n");
	
	FunChoice();
}

// 控制字体颜色
void setColorAndBackground(WORD wAttributes){
    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hStdout, wAttributes);
}

// 功能跳转函数
void FunChoice(){
	int choice, flag = 0;
	
	while (!flag) {
		printf("\t    请输入你要进行的操作数：");
		scanf("%d", &choice);
		
		switch (choice) {
			case 1:
				GetLunar();
				flag = 1;
				break;
			case 2:
				GetGre();
				flag = 1;
				break;
			case 3:
				PrintMonth(0, 0);
				flag = 1;
				break;
			case 4:
				GetDays();
				flag = 1;
				break;
			case 5:
				GetDates();
				flag = 1;
				break;
			case 6:
				DiffInDays();
				flag = 1;
				break;
			case 7:
				PrintSolarTerms();
				flag = 1;
				break;
			case 8:
				GetFestival();
				flag = 1;
				break;
			default:
				setColorAndBackground(FOREGROUND_RED | BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
				printf("\t\t请输入正确的操作数！\n"); // 错误提示标红
				setColorAndBackground(BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
				break;
		}
	}
}

// 获取当前时间
void GetCurTime () {
	time(&nowtime); // 获取时间戳
	NT = localtime(&nowtime); // 转化为本地时间
	
	printf("\t    今天是%d年%d月%d日\n", NT->tm_year + 1900, NT->tm_mon + 1, NT->tm_mday);
	
	NowDate[0] = NT->tm_year + 1900;
	NowDate[1] = NT->tm_mon + 1;
	NowDate[2] = NT->tm_mday;
}

// 获取农历某年某月的天数
static int GetLunarMonthDays(int year, int month, int isLeap) { 
    int offset = year - 1900;
    if (offset < 0 || offset >= sizeof(LUNAR_INFO)/sizeof(LUNAR_INFO[0])) 
		return 0;
    
    unsigned int info = LUNAR_INFO[offset];
    int leap = info & 0xf;
    
    if (isLeap) {
        if (leap != month) 
			return 0;
			
        return (info & (0x10000 >> leap)) ? 30 : 29;
    }
    
    return (info & (0x8000 >> (month-1))) ? 30 : 29;
}

// 判断公历日期是否正确
bool isRightGreDate (int y = 1, int m = 1, int d = 1) {
	if (m == 1 || m == 3 || m == 5 || m ==7 || m == 8 || m == 10 || m == 12) {
		if(d <= 0 || d >= 32)
			return false;
		else
			return true;
	}
	else if (m == 2) {
		if ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0) {
			if (d <= 0 || d >= 30)
				return false;
			else 
				return true;
		}
		else {
			if (d <= 0 || d >= 29)
				return false;
			else
				return true;
		}
	}
	else {
		if(d <= 0 || d >= 31)
			return false;
		else
			return true;
	}
}

// 判断农历日期是否正确
bool isRightLunarDate (int lunarYear, int lunarMonth, int lunarDay, int isLeap) {
    if (lunarMonth < 1 || lunarMonth > 12) 
		return false;
    
    // 获取当年闰月信息
    unsigned int yearInfo = LUNAR_INFO[lunarYear - 1900];
    int leapMonth = yearInfo & 0xf;
    
    // 检查闰月
    if (isLeap && leapMonth != lunarMonth) 
		return false;
    
    // 检查日期
    int maxDays = GetLunarMonthDays(lunarYear, lunarMonth, isLeap);
    if (lunarDay < 1 || lunarDay > maxDays) 
		return false;
    
    return true;
}

// 获取星期数
int GetWeekDay (int year, int month, int day) {
    if (month == 1 || month == 2) {
        month += 12;
        year--;
    }
    
    return (day + 2 * month + 3 * (month + 1) / 5 + year + year / 4 - year / 100 + year / 400) % 7;
}

// 获取天干地支
const char* getGanZhi(int year) {
    static char ganzhi[10];
    int gan = (year - 4) % 10;
    int zhi = (year - 4) % 12;
    
    if (gan < 0) 
		gan += 10;
		
    if (zhi < 0) 
		zhi += 12;
		
    sprintf(ganzhi, "%s%s", Gan[gan], Zhi[zhi]);
	return ganzhi;
}

// 简化处理：假设每月的节气在1日和15日
const char* GetSolarTerms(int month, int day) { 
    if (day == 1 || day == 15) {
        int termIndex = (month - 1) * 2 + (day == 15 ? 1 : 0);
        
        if (termIndex == 0)
        	termIndex = 22;
        else if(termIndex == 1)
        	termIndex = 23;
        else
        	termIndex -= 2;
        
        return terms[termIndex].name;
    }
    
    return NULL;
}

// 1.查询农历
void GetLunar () {
	system("cls");
    int date[4];
    int flag1 = 0;
    
	do{
		printf("请输入公历日期(格式为年 月 日)：");
		scanf("%d %d %d", &date[0], &date[1], &date[2]);
		
		if (isRightGreDate(date[0], date[1], date[2]))
			flag1 = 1;
		else if (date[0] > 2100 || date[0] < 1900){
			setColorAndBackground(FOREGROUND_RED | BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
			printf("超出本万年历的最大时间范围！\n\n");
			setColorAndBackground(BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
		}
		else {
			setColorAndBackground(FOREGROUND_RED | BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
			printf("请输入正确的公历日期！\n");
			setColorAndBackground(BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
		}
			
	} while (!flag1);
    
    printf("\n1. 查询日期所在的当月月历：\n");
    PrintMonth(date[0], date[1]);
    printf("(此处节气仅供参考，可使用万年历功能7获取较为准确的节气信息)");

    printf("\n2. 天干地支：");
	printf("%s", getGanZhi(date[0]));
	printf("年\n");

    const char* currentTerm = GetSolarTerms(date[1], date[2]);
    
    if (currentTerm) 
        printf("\n3. 节气信息：今天是%s节气\n", currentTerm);
	else { 
        int daysToNext = (date[2] <= 15) ? 15 - date[2] : MonthDays[date[1] - 1] - date[2] + 1;
        printf("\n3. 节气信息：距离下一个节气还有%d天\n", daysToNext);
    }
    
    printf("(此处节气仅供参考，可使用万年历功能7获取较为准确详细的节气信息)\n");

    printf("\n4. 当月的节气日期：\n");
    printf("   %d月1日：%s\n", date[1], terms[(date[1] - 1) * 2].name);
    printf("   %d月15日：%s\n\n", date[1], terms[(date[1] - 1) * 2 + 1].name);
}

// 获取农历某年的总天数
static int GetLunarYearDays (int year) { 
    int i, sum = 348; // 假设无闰月，且均为小月
    int offset = year - 1900;
    
    if (offset < 0 || offset >= sizeof(LUNAR_INFO)/sizeof(LUNAR_INFO[0])) 
		return 0; // 报错警示
    
    unsigned int info = LUNAR_INFO[offset];
    int leap = info & 0xf; // 判断是否是闰月
    
    for(i = 0x8000; i > 0x8; i >>= 1)
        sum += (info & i) ? 1 : 0;
    
    if(leap)
        sum += (info & (0x10000 >> leap)) ? 30 : 29;
    
    return sum;
}

// 农历转换为公历
void lunarToGregorian(int lunarYear, int lunarMonth, int lunarDay, int isLeap, int* gregYear, int* gregMonth, int* gregDay) {
    int days = 0; // 计算从1900年1月31日到指定农历日期的天数
    
    for (int year = 1900; year < lunarYear; year++)
        days += GetLunarYearDays(year);
    
    // 计算当年正月到目标月份的天数
    unsigned int yearInfo = LUNAR_INFO[lunarYear - 1900];
    int leapMonth = yearInfo & 0xf;
    
    for (int i = 1; i < lunarMonth; i++) {
        days += GetLunarMonthDays(lunarYear, i, 0);
        if (i == leapMonth) {
            days += GetLunarMonthDays(lunarYear, i, 1);
        }
    }
    
    // 如果是闰月，且当前月份大于闰月，需要加上闰月的天数
    if (isLeap && lunarMonth == leapMonth)
        days += GetLunarMonthDays(lunarYear, lunarMonth, 0);
    
    days += lunarDay - 1; // 加上当月的天数
    
    *gregYear = 1900;
    *gregMonth = 1;
    *gregDay = 31;
    
    while (days > 0) {
        int yearDays = ((*gregYear % 4 == 0 && *gregYear % 100 != 0) || (*gregYear % 400 == 0)) ? 366 : 365;
        if (days >= yearDays) {
            days -= yearDays;
            (*gregYear)++;
            continue;
        }
        
        int monthDays = MonthDays[*gregMonth - 1];
        if (*gregMonth == 2 && ((*gregYear % 4 == 0 && *gregYear % 100 != 0) || (*gregYear % 400 == 0))) {
            monthDays++;
        }
        
        if (days >= monthDays) {
            days -= monthDays;
            (*gregMonth)++;
            if (*gregMonth > 12) {
                *gregMonth = 1;
                (*gregYear)++;
            }
            continue;
        }
        
        *gregDay += days;
        if (*gregDay > monthDays) {
            *gregDay -= monthDays;
            (*gregMonth)++;
            if (*gregMonth > 12) {
                *gregMonth = 1;
                (*gregYear)++;
            }
        }
        break;
    }
}

// 2.查询公历
void GetGre() {
    system("cls");
	int flag2 = 0;
	int lunardate[4];
	int isLeap = 0;  // 默认非闰月
	
	do{
		printf("请输入农历日期(格式为年 月 日)：");
		scanf("%d %d %d", &lunardate[0], &lunardate[1], &lunardate[2]);
		
		if (isRightLunarDate(lunardate[0], lunardate[1], lunardate[2], isLeap))
			flag2 = 1;
		else if (lunardate[0] > 2100 || lunardate[0] < 1900){
			setColorAndBackground(FOREGROUND_RED | BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
			printf("超出本万年历的最大时间范围！\n\n");
			setColorAndBackground(BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
		}
		else{
			setColorAndBackground(FOREGROUND_RED | BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
			printf("请输入正确的农历日期！\n");
			setColorAndBackground(BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
		}
			
	} while (!flag2);	
    
    int gregYear, gregMonth, gregDay;
    lunarToGregorian(lunardate[0], lunardate[1], lunardate[2], isLeap, &gregYear, &gregMonth, &gregDay);

    printf("\n农历：%d年%s月%s\n", 
           lunardate[0], 
           LunarMonths[lunardate[1]-1], 
           LunarDays[lunardate[2]-1]);

    printf("对应的公历日期是：%d年%d月%d日\n\n", gregYear, gregMonth, gregDay);
}

// 月历中的农历表示
const char* numberToChinese(int num) {
    static char result[10];
    result[0] = '\0';
    
    if (num <= 10)
        strcpy(result, ChineseNums[num]);
    else if (num < 20)
        sprintf(result, "十%s", num % 10 ? ChineseNums[num % 10] : "");
    else
        sprintf(result, "%s十%s", ChineseNums[num / 10], num % 10 ? ChineseNums[num % 10] : "");
    
    return result;
}

// 简化算法：公历转农历函数
const char* getLunarDayShort(int year, int month, int day) {
    static char shortLunarDay[10];
    int lunarDay = (day + 10) % 30; 
    
    if (lunarDay == 0)
        strcpy(shortLunarDay, "三十");
    else if (lunarDay < 11)
        sprintf(shortLunarDay, "初%s", numberToChinese(lunarDay));
    else if (lunarDay < 20)
        sprintf(shortLunarDay, "十%s", lunarDay == 10 ? "" : numberToChinese(lunarDay % 10));
    else if (lunarDay == 20)
        strcpy(shortLunarDay, "二十");
    else
        sprintf(shortLunarDay, "廿%s", numberToChinese(lunarDay % 10));
    
    return shortLunarDay;
}

// 3.打印月历
void PrintMonth(int year, int month) {
	system("cls");
	int flag3 = 0;
	
	if(year == 0 && month == 0){ // 调用功能3
		do{
			printf("请输入要查询的年月：");
			scanf("%d %d", &year, &month);
			
			if(isRightGreDate(year, month) == 1)
				flag3 = 1;
			else if (year > 2100 || year < 1900){
				setColorAndBackground(FOREGROUND_RED | BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
				printf("请输入正确的公历日期！\n");
				setColorAndBackground(BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
			}
			else {
				setColorAndBackground(FOREGROUND_RED | BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
				printf("请输入正确的日期！\n\n");
				setColorAndBackground(BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
			}
		}while(!flag3);
	}

    printf("\n%d年%d月日历：\n", year, month);
    printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");
    setColorAndBackground(FOREGROUND_RED | BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
    printf("日");
    setColorAndBackground(BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
    printf("       一      二      三      四      五       ");
    setColorAndBackground(FOREGROUND_RED | BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
    printf("六    \n");
    setColorAndBackground(BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
    printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");
    
    int firstDay = GetWeekDay(year, month, 1); // 计算该月第一天是星期几
    int daysInMonth; // 获取该月的天数
    
    if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) 
	    daysInMonth = 29;
	else   
	    daysInMonth = MonthDays[month - 1];
    
    for (int i = 0; i < firstDay; i++)
        printf("        ");
    
    int currentDay = 1; // 用于跟踪当前行的位置
    int position = firstDay;

    while (currentDay <= daysInMonth) {
    	if(position == 6 || position == 0)
    		setColorAndBackground(FOREGROUND_RED | BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
    		
        printf(" %-3d    ", currentDay); // 打印公历日期
        setColorAndBackground(BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
        
        if (position == 6 || currentDay == daysInMonth) {
            printf("\n"); // 如果到达周六或月末，打印换行
            
            int startDay = currentDay - position; // 回退打印农历/节气
            if (startDay < 1) 
				startDay = 1;
				
			int mark = position - (currentDay - startDay);
            
            for (int i = 0; i < (startDay == 1 ? firstDay : 0); i++) 
                printf("        "); // 打印前导空格（与上一行对齐）
            
            for (int day = startDay; day <= currentDay; day++) { // 打印农历或节气
                const char* term = GetSolarTerms(month, day);
                
				if (term != NULL) {
					setColorAndBackground(FOREGROUND_RED | BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
                    printf(" %-6s ", term);
                    setColorAndBackground(BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
				}
				else {
                    const char* lunar = getLunarDayShort(year, month, day);
                    
                    if(mark == 0 || mark == 6)
                    	setColorAndBackground(FOREGROUND_RED | BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
						
					printf(" %-6s ", lunar);
					setColorAndBackground(BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
					
                }
                
                mark++;
            }
            
            printf("\n");
            if (currentDay != daysInMonth)
                printf("\n"); 
            
            position = 0;
        } 
		else
            position++;
            
        currentDay++;
    }
    
    printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");
}

// 两日期之间的天数差
int days_between_dates (int* date1_int, int* date2_int) {  
    struct tm date1_tm = {}, date2_tm = {};  
	
	date1_tm.tm_year = date1_int[0] - 1900;
	date1_tm.tm_mon = date1_int[1] - 1;
	date1_tm.tm_mday = date1_int[2]; // 把对应日期转化为tm结构体格式
	
	date2_tm.tm_year = date2_int[0] - 1900;
	date2_tm.tm_mon = date2_int[1] - 1;
	date2_tm.tm_mday = date2_int[2];


    time_t t1 = mktime(&date1_tm);  
    time_t t2 = mktime(&date2_tm);  //获取时间秒数

    return abs(difftime(t2,t1)/(60*60*24));  // 返回天数差
} 

// 4.天数差
void GetDays () { // 距离今天的天数
	system("cls");
	
	int date[4] = {0}, flag4 = 0, result4;
	int early = 0, late = 0;
	
	do{
		printf("请输入需要查询的日期(格式为年 月 日)：");
		scanf("%d %d %d", &date[0], &date[1], &date[2]);
		
		if (isRightGreDate(date[0], date[1], date[2]))
			flag4 = 1;
		else if(date[0] > 2037 || date[0] < 1970){
			setColorAndBackground(FOREGROUND_RED | BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
			printf("超出可查询的时间范围！\n\n");
			setColorAndBackground(BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
		}

		else {
			setColorAndBackground(FOREGROUND_RED | BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
			printf("请输入正确的日期！\n");
			setColorAndBackground(BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
		}
			
	} while (!flag4);
	
	if(date[0] < NowDate[0])
		early = 1;
	else if (date[0] > NowDate[0])
		late = 1;
	else {
		if (date[1] < NowDate[1])
			early = 1;
		else if (date[1] > NowDate[1])
			late = 1;
		else {
			if (date[2] < NowDate[2])
				early = 1;
			else if (date[2] > NowDate[2])
				late = 1;
		}
	}
	
	result4 = days_between_dates (NowDate, date);
	
	if (early == 1 && late == 0)
		printf("\n%d-%d-%d 比今天(%d-%d-%d)早%d天\n\n", date[0], date[1], date[2], NowDate[0], NowDate[1], NowDate[2], result4);
	else if (early == 0 && late == 1)
		printf("\n%d-%d-%d 比今天(%d-%d-%d)晚%d天\n\n", date[0], date[1], date[2], NowDate[0], NowDate[1], NowDate[2], result4);
	else
		printf("\n%d-%d-%d 就是今天", date[0], date[1], date[2]);
}

// 5.获取日期
void GetDates () { //距离今天相应天数的日期
	system("cls");
	int gap;
	printf("请输入所要查询日期与今天的天数差：");
	scanf("%d", &gap);
	
	time_t diffday = nowtime - (time_t)gap*60*60*24;
	tm* diffdate = localtime(&diffday);
	
	printf("\n距离今天(%d-%d-%d)%d天的日期为：\n", NowDate[0], NowDate[1], NowDate[2], gap);
	printf("%d年%d月%d日 ", diffdate->tm_year+1900, diffdate->tm_mon+1, diffdate->tm_mday);
	printf("(星期%s)\n", weekdays[GetWeekDay(diffdate->tm_year+1900, diffdate->tm_mon+1, diffdate->tm_mday)]);
	
	diffday = nowtime + (time_t)gap*60*60*24;
	diffdate = localtime(&diffday);
	
	printf("%d年%d月%d日 ", diffdate->tm_year+1900, diffdate->tm_mon+1, diffdate->tm_mday);
	printf("(星期%s)", weekdays[GetWeekDay(diffdate->tm_year+1900, diffdate->tm_mon+1, diffdate->tm_mday)]);
	printf("\n\n");
}

// 6.任意两天的天数差
void DiffInDays () { 
	system("cls");

	int date1[4] = {0}, date2[4] = {0};
	int flag61 = 0, flag62 = 0, result6;
	
	do {
		printf("请输入第一个日期(格式为年 月 日)：");
		scanf("%d %d %d", &date1[0], &date1[1], &date1[2]);
		
		if (isRightGreDate(date1[0], date1[1], date1[2]))
			flag61 = 1;
		else if (date1[0] > 2037 || date1[0] < 1970){
			setColorAndBackground(FOREGROUND_RED | BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
			printf("超出本万年历的查询范围！\n\n");
			setColorAndBackground(BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
		}
		else {
			setColorAndBackground(FOREGROUND_RED | BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
			printf("请输入正确的日期！\n\n");
			setColorAndBackground(BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
		}
	} while (!flag61);
	
	do {
		printf("请输入第二个日期(格式为年 月 日)：");
		scanf("%d %d %d", &date2[0], &date2[1], &date2[2]);
		
		if (isRightGreDate(date2[0], date2[1], date2[2]))
			flag62 = 1;
		else if(date2[0] > 2037 || date2[0] < 1970){
			setColorAndBackground(FOREGROUND_RED | BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
			printf("超出本万年历的查询范围，请重新输入！\n\n");
			setColorAndBackground(BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
		}		
		else {
			setColorAndBackground(FOREGROUND_RED | BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
			printf("请输入正确的日期！\n\n");
			setColorAndBackground(BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
		}
	} while (!flag62);
	
	result6 = days_between_dates(date1, date2);
	
	printf("\n%d年%d月%d日 与 %d年%d月%d日 相差%d天。\n\n", date1[0], date1[1], date1[2], date2[0], date2[1], date2[2], result6);
}

// 计算精确节气
int CalculateSolarTerm(int year, double param) {
    // 修正闰年计算误差
    int leap_correction = ((year-1)/4 - (year-1)/100 + (year-1)/400) 
                        - ((1999)/4 - (1999)/100 + (1999)/400);
                        
    return (int)floor(year * 0.2422 + param - 486.0) - leap_correction;
}

// 7.打印某年节气
void PrintSolarTerms () {
	system("cls");
    int input_year, flag7 = 0;
    
    do {
    	printf("请输入要查询的年份：");
    	scanf("%d", &input_year);
    	
    	if(input_year > 1900 && input_year < 2100)
    		flag7 = 1;
		else{
			setColorAndBackground(FOREGROUND_RED | BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
			printf("超出本万年历时间范围！请重新输入！\n\n");
			setColorAndBackground(BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
		}
    }while (!flag7);
    
    printf("\n======== %d年二十四节气表 =========\n", input_year);
    
    for (int i = 0; i < 24; i++) {
        int day = CalculateSolarTerm(input_year, terms[i].param);
        int actual_month = terms[i].month + (day > 31 ? 1 : 0);
        int actual_day = day > 31 ? day-31 : day; // 处理跨月情况
        
        printf("\t%2d月%2d日：%s\n", 
            actual_month, 
            actual_day,
            terms[i].name);
    }
    
    printf("\n");
}

// 打印公历节日
void PrintGreFestival () {
	int chosemonth, flag8 = 0;
	
	do{
		printf("请输入想要查询节日的月份：");
		scanf("%d", &chosemonth);
		
		if(chosemonth > 0 && chosemonth < 13)
			flag8 = 1;
		else {
			setColorAndBackground(FOREGROUND_RED | BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
			printf("请输入正确的月份！\n\n");
			setColorAndBackground(BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
		}
	}while(!flag8);
	
	system("cls");
	
	printf("以下是每年%d月份的公历节日：\n\n", chosemonth);
	
	switch (chosemonth) {
		case 1:
			printf("1月1日     元旦\n");
			printf("1月10日    中国人民警察节\n");
			break;
		case 2:
			printf("2月10日    国际气象节\n");
			printf("2月14日    情人节\n\n");
			break;
		case 3:
			printf("3月8日     国际妇女节\n");
			printf("3月12日    植树节\n");
			printf("3月15日    消费者权益日\n\n");
			break;
		case 4:
			printf("4月1日     愚人节\n");
			printf("4月7日     世界卫生日\n");
			printf("4月15日    国家安全教育日\n\n");
			break;
		case 5:
			printf("5月1日            国际劳动节\n");
			printf("5月4日            青年节\n");
			printf("5月第二个星期日   母亲节\n");
			printf("5月31日           世界无烟日\n\n");
			break;
		case 6:
			printf("6月1日            国际儿童节\n");
			printf("6月第三个星期日   父亲节\n\n");
			break;
		case 7:
			printf("7月1日     建党日\n");
			printf("7月30日    国际友谊日\n\n");
			break;
		case 8:
			printf("8月1日     建军节\n");
			printf("8月12日    国际青年节\n\n");
			break;
		case 9:
			printf("9月10日    教师节\n\n");
			break;
		case 10:
			printf("10月1日    国庆节\n");
			printf("10月24日   程序员节\n\n");
			break;
		case 11:
			printf("11月1日    万圣节\n");
			printf("11月17日   国际大学生节\n\n");
			break;
		case 12:
			printf("12月1日     世界艾滋病日\n");
			printf("12月4日     国家宪法日\n");
			printf("12月13日    南京大屠杀死难者国家公祭日\n");
			printf("12月24日    平安夜\n");
			printf("12月25日    圣诞节\n\n");
			break;
	}
}

// 打印农历节日
void PrintLunarFestival () {
	system("cls");
	
	printf("以下是我国主要的农历节日：\n\n");
	printf("正月初一      春节\n");
	printf("正月十五      元宵节\n");
	printf("二月初二      龙抬头\n");
	printf("三月初三      上巳节\n");
	printf("4月5日前后    清明节\n");
	printf("五月初五      端午节\n");
	printf("七月初七      七夕节\n");
	printf("七月十五      中元节\n");
	printf("八月十五      中秋节\n");
	printf("九月初九      重阳节\n");
	printf("腊月初八      腊八节\n\n");
}

// 8.节日
void GetFestival () {
	int numchoice, flag8 = 0;
	
	system("cls");
	
	do {
		printf("查询公历节日请按'1'，查询农历节日请按'2'：");
			scanf("%d", &numchoice);
					
		if (numchoice == 1 || numchoice == 2)
			flag8 = 1;
		else{
			setColorAndBackground(FOREGROUND_RED | BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
			printf("\n请输入正确的指令！\n");
			setColorAndBackground(BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
		}
			
	} while (!flag8);
	
	if (numchoice == 1)
		PrintGreFestival(); //打印公历节日
	else 
		PrintLunarFestival(); //打印农历节日
}

int main() {
	SetConsoleTitleA("万年历"); //设置标题
	
	char input;
	int exitFlag = 0;
	
	display(); // 查询系统主界面
	getchar();
	
	while (!exitFlag) {
		printf("按Enter退出系统，按'1'返回主菜单：");
		
		input = getchar();
		
		if (input == '1') {
			display();
			getchar();
		}
		else if (input == '\n')
			exitFlag = 1; // 已退出查询系统
		else {
			setColorAndBackground(FOREGROUND_RED | BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
			printf("\n请输入正确命令。\n"); // 错误提示标红
			setColorAndBackground(BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
			exitFlag = 0;
			getchar();
		}
	}

	return 0;
}
